package top.cardone.data.jdbc.dao.impl;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import top.cardone.context.ApplicationContextHolder;
import top.cardone.data.dao.PageDao;
import top.cardone.data.support.PageSupport;
import top.cardone.data.support.PageableSupport;

import java.util.List;
import java.util.Map;

/**
 * Created by yao hai tao on 2015/8/26.
 */
public class PageDaoImpl extends SimpleDaoImpl implements PageDao {
	@Override
	public Page<Map<String, Object>> page(Object page) {
		String countSqlFilePath = this.getSqlFilePath("page.count");
		String findListSqlFilePath = this.getSqlFilePath("page.find");

		Map<String, Object> pageMap = this.toMap(page, "page");

		return this.page(countSqlFilePath, findListSqlFilePath, pageMap);
	}

	protected Page<Map<String, Object>> page(String countSqlFilePath, String findListSqlFilePath, Map<String, ?> page) {
		final long totalSize = this.readOne(Long.class, countSqlFilePath, page);

		if (totalSize < 1) {
			return ApplicationContextHolder.getBean(PageSupport.class).newPage(Lists.newArrayList(), page, totalSize);
		}

		Pageable pageable = ApplicationContextHolder.getBean(PageableSupport.class).newPageable(page);

		Map<String, Object> newPage = Maps.newHashMap(page);

		newPage.put("pageNumber", pageable.getPageNumber());
		newPage.put("pageSize", pageable.getPageSize());
		newPage.put("offset", pageable.getOffset());

		List<Map<String, Object>> findList = this.findList(findListSqlFilePath, newPage);

		return ApplicationContextHolder.getBean(PageSupport.class).newPage(findList, page, totalSize);
	}

	@Override
	public <P> Page<P> page(Class<P> mappedClass, Object page) {
		String countSqlFilePath = this.getSqlFilePath("page.count");
		String findListSqlFilePath = this.getSqlFilePath("page.find");

		Map<String, Object> pageMap = this.toMap(page, "page");

		return this.page(mappedClass, countSqlFilePath, findListSqlFilePath, pageMap);
	}

	protected <P> Page<P> page(Class<P> mappedClass, String countSqlFilePath, String
			findListSqlFilePath, Map<String, ?> page) {
		final long totalSize = this.readOne(Long.class, countSqlFilePath, page);

		if (totalSize < 1) {
			return ApplicationContextHolder.getBean(PageSupport.class).newPage(Lists.newArrayList(), page, totalSize);
		}

		Pageable pageable = ApplicationContextHolder.getBean(PageableSupport.class).newPageable(page);

		Map<String, Object> newPage = Maps.newHashMap(page);

		newPage.put("pageNumber", pageable.getPageNumber());
		newPage.put("pageSize", pageable.getPageSize());
		newPage.put("offset", pageable.getOffset());

		List<P> findList = this.findList(mappedClass, findListSqlFilePath, newPage);

		return ApplicationContextHolder.getBean(PageSupport.class).newPage(findList, page, totalSize);
	}
}